/*
@filename		:  array.js
@description	: Array basic methods
-----------------------------------------------------------------------------
@author	:  ScriptPower     <a href="mailto:scriptpower@qq.com">scriptpower@qq.com</a>
@update	:  2010-12-30
*/
(function (S){
		//JS1.6
		var toString =Object.prototype.toString,
			slice	 = Array.prototype.slice,
			type	= S.type,
			//测试数组类型
			/*test	= function (o){	//0: 非数组	1:array	 2:arrayLike
				var r = 0, 	t;
				if (o) {
					if (toString.call(o) === "[object Array]") {//array
						r = 1;
					} else if((t = typeof(o)) && (t =="object" || t == "function")){
						try {
							if (('length' in o) && !o.tagName && !o.alert && !o.apply) {//arrayLike
								r = 2;
							}
						} catch(e) {}
					}
				}
				return r;
			},

			//isArray
			isArray	 = Array.isArray || function (o){
				return '[object Date]' === toString.call(o) && o.toString() !== 'Invalid Date' && !isNaN(o);
			},*/

			//JS1.6	: forEach
			/*
			forEach = Array.forEach || function (array, callback , thisp) {
				var i = 0, l = array.length;
				for(; i<l ; i++) callback.call(thisp , array[i] , i, array);
			},*/

			//JS1.6	: map
			map = Array.map || function (array, callback , thisp){
				var ret= [],	i = 0,l = array.length;
				//if(type(callback) === "function" ){
					for(; i<l ; i++) {
						ret[i] = callback.call( thisp, array[i], i , array);
					}
					return ret;
				//} else {
					//for(; i<l ; i++) ret[i] = array[i];
					//return slice.call(array,0 );	//update: 2010/12/6 lei
				//}
			},

			//JS1.6	: indexOf
			indexOf = Array.indexOf || function (array, value , startIndex){
				var ret = -1, l = array.length;
				while(startIndex < l){
					if(array[startIndex] === value){
						ret = startIndex;
						break;
					}
					startIndex ++ ;
				}
				return ret;
			},

			//JS1.6	: lastIndexOf
			lastIndexOf = Array.lastIndexOf || function (array, value , startIndex){
				var ret=-1;
				while(startIndex >= 0){
					if(array[startIndex] === value){
						ret = startIndex;
						break;
					}
					startIndex--;
				}
				return ret;
			},

			//JS1.6	: every
			every = Array.every || function (array, callback , thisp){
				var ret = true,
					i = 0 ,
					l = array.length;
				//if(S.type(callback) == "function"){
					for(; i<l;i++) {
						if(!callback.call(thisp, array[i], i, array)){
							ret = false;
							break;
						}
					}
				//} else {
					//throw callback +" is not a function.";
					//throw new TypeError();
				//}
				return ret;
			},

			//JS1.6	: some
			some = Array.some || function (array, callback , thisp){
				var ret = false, i = 0 ,	l = array.length;

				//if(S.type(callback) == "function") {
					for(; i<l;i++) {
						if(callback.call(thisp, array[i], i, array)){
							ret = true;
							break;
						}
					}
				//} else {
					//throw callback +" is not a function.";
					//throw new TypeError();
				//}
				return ret;
			},

			//JS1.6	: filter
			filter = Array.filter || function (array, callback /*, thisp*/){
				var ret =[],
					i=0,
					l=array.length,
					thisp = arguments[2] || S;
				//if(S.type(callback) == "function"){
					for(; i<l;i++) {
						if(callback.call(thisp, array[i], i, array)) {
							ret.push( array[i] );
						}
					}
				//}
				return ret;
			},

			//JS1.8.5	: reduce
			reduce ,

			//JS1.8.5	: reduceRright
			reduceRright,

			//remove
			remove	= function (array, callback /*, thisp*/){
				var i = array.length-1,
					type = typeof(callback),
					thisp;
				if(type == "function"){
					thisp = arguments[2] || S;
					while(i >= 0){
						if(callback.call(thisp, array[i], i, array)) {
							array.splice(i ,1);
						}
						i--;
					}
				} else if(type == "number"){
					if(callback>=0 && callback <= i) array.splice(callback ,1);
				}
				return this;
				//return array;
			};



		//define
		S.define( S.Array,
			true,	//重新定义
			//"test", test,
			//"isArray", isArray,
			//"forEach", function (array, callback /*, thisp*/){
				//forEach(array, callback ,arguments[2] || S);
				//return this;
			//},
			"map", function (array, callback /*, thisp*/){
				return map(array, callback ,arguments[2] || S);
			},
			"indexOf", function (array, callback /*, startIndex*/){
				var startIndex = arguments[2], l = array.length;
				if(typeof(startIndex) != "number"){
					startIndex = 0;
				} else if(startIndex < 0) {
					startIndex += l;
					if(startIndex < 0) startIndex =0;
				}
				return indexOf(array, callback ,arguments[2] || 0);
			},
			"lastIndexOf", function (array, callback /*, startIndex*/){
				var startIndex = arguments[2], l = array.length - 1;
				if(typeof(startIndex) != "number" ||  startIndex > l){
					startIndex = l;
				} else if(startIndex < 0){
					startIndex += l;
				}
				return lastIndexOf(array, callback ,startIndex);
			},
			"every", function (array, callback /*, thisp*/){
				return every(array, callback ,arguments[2] || S);
			},
			"some", function (array, callback /*, thisp*/){
				return some(array, callback ,arguments[2] || S);
			},
			"filter", function (array, callback /*, thisp*/){
				return filter(array, callback ,arguments[2] || S);
			},
			"remove", function (array, callback /*, thisp*/){
				remove(array, callback ,arguments[2] || S);
				return this;
			});
		//alert(S.Array.every);
})(SP);